//////////////////////////////////////////////////////////////////////////
// $Id: MObject.cpp,v 1.1 2009/04/03 12:46:10 sunjun Exp $
//////////////////////////////////////////////////////////////////////////

#include "Local.h"

//////////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////////

NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////////

	// the dynamic creator
	MIMPLEMENT_DYNCREATOR(MObject)

	//////////////////////////////////////////////////////////////////////////

	MObject::MObject()
	{
		GUARD(MObject::MObject);

	//	this->property("ColorBits",MNEW(MProperty((U32)32)));
	//	this->property("DepthBits",MNEW(MProperty((U32)24)));

		UNGUARD;
	}

	MObject::~MObject()
	{
		GUARD(MObject::~MObject);

		UNGUARD;
	}

	//////////////////////////////////////////////////////////////////////////
	
	// root of dispatch maps
	const MDISP_MAP MObject::__disp_map =
	{
		NULL,
		&MObject::__disp_entries[0]
	};

	const MDISP_MAP* MObject::getThisDispatchMap()
	{
		return &MObject::__disp_map;
	}

	const MDISP_MAP* MObject::getDispatchMap() const
	{
		return &MObject::__disp_map;
	}

	const MDISP_MAP_ENTRY MObject::__disp_entries[] =
	{
		{ "safe", (MDISP_MFN)(VOID (MReference::*)(const MVar *argv))&MReference::safe, (MDISP_AFN)(DARG1<VOID,BOOL>(&DARGFN1)) },
		{ 0, 0, 0 }     // nothing here
	};

	/*
	====================
	invoke
	====================
	*/
	INLINE BOOL MObject::invoke( const CHAR* name, const MVar *argv )
	{
		GUARD(MObject::invoke);

		const MDISP_MAP * disp_map = getDispatchMap();
		while( disp_map != NULL )
		{
			// find the entry where (entry->name == name)
			const MDISP_MAP_ENTRY* entry = disp_map->entries;
			while( entry->name != NULL )
			{
				if( Str(entry->name) == name )
				{
					// call the dispatch function
					entry->afn( this, entry->mfn, argv );
					return TRUE;
				}
				
				++entry;
			}
			
			// check the base class
			if(disp_map->getBaseDispatchMap == NULL) break;
			disp_map = (*disp_map->getBaseDispatchMap)();
		}
		
		return FALSE;

		UNGUARD;
	}

	/*
	====================
	property
	====================
	*/
	INLINE VOID MObject::property( const CHAR* prop_name, const MProperty* prop_ptr )
	{
		GUARD(MObject::property);

		THREAD_AUTO_LOCK;
		std::map<Str, MPropertyPtr>::iterator it = mPropMap.find(prop_name);
		CHECK(it==mPropMap.end()&&"The property is existent already!\n");
		mPropMap.insert( std::map<Str, MPropertyPtr>::value_type(prop_name, (MProperty*)prop_ptr) );

		UNGUARD;
	}

	INLINE const MProperty* MObject::property( const CHAR* prop_name ) const
	{
		GUARD(MObject::property);

		THREAD_AUTO_LOCK;
		std::map<Str, MPropertyPtr>::const_iterator it = mPropMap.find(prop_name);
		if(it!=mPropMap.end()) return it->second.ptr();
		return NULL;

		UNGUARD;
	}
	
//////////////////////////////////////////////////////////////////////////
	
NAMESPACE_END
		
//////////////////////////////////////////////////////////////////////////
